package com.atguigu.scw.member.controller;

import com.atguigu.scw.member.ResultEntity;
import com.atguigu.scw.member.api.MysqlRemoteService;
import com.atguigu.scw.member.api.RedisRemoteService;
import com.atguigu.scw.member.config.ShortMessageProperties;
import com.atguigu.scw.member.po.MemberPO;
import com.atguigu.scw.member.util.SCWUtils;
import com.atguigu.scw.member.vo.MemberLoginVO;
import com.atguigu.scw.member.vo.MemberVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Controller
public class MemberController {

    @Autowired
    private ShortMessageProperties shortMessageProperties;
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MysqlRemoteService mysqlRemoteService;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    private final String redisCodePrefix = "REDIS_CODE_PREFIX_";

    @ResponseBody
    @RequestMapping("/auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {
        // 发送验证码到phoneNum手机
        ResultEntity<String> sendMessageResult = SCWUtils.sendShortMessage(
                shortMessageProperties.getHost(), shortMessageProperties.getPath(),
                shortMessageProperties.getAppCode(), phoneNum,
                shortMessageProperties.getSign(), shortMessageProperties.getSkin()
        );
        // 判断短信发送结果
        if (ResultEntity.SUCCESS.equals(sendMessageResult.getResult())) {
            // 如果发送成功，则将验证码存入Redis
            String code = sendMessageResult.getData();
            String key = redisCodePrefix + phoneNum;
            ResultEntity<String> saveCodeResult = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15L, TimeUnit.MINUTES);
            if (ResultEntity.SUCCESS.equals(saveCodeResult.getResult())) {
                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResult;
            }
        } else {
            return sendMessageResult;
        }
    }

    @RequestMapping("/auth/member/register")
    public String register(MemberVO memberVO, ModelMap modelMap) {
        // 获取用户手机号
        String phoneNum = memberVO.getPhoneNum();
        // 拼接Redis中的key
        String key = redisCodePrefix + phoneNum;
        // 从Redis中获取对应的value
        ResultEntity<String> result = redisRemoteService.getRedisStringValueByKeyRemote(key);
        // Redis中验证码和表单中验证码比较
        if (ResultEntity.FAILED.equals(result.getResult())) {
            modelMap.addAttribute("message", result.getMessage());
            return "member-reg";
        }
        String value = result.getData();
        if (value == null) {
            modelMap.addAttribute("message", "验证码已过期！请检查手机号是否正确或者重新发送！");
            return "member-reg";
        }
        if (!Objects.equals(value, memberVO.getCode())) {
            modelMap.addAttribute("message", "验证码不正确！");
            return  "member-reg";
        }
        // 验证码一致，则从Redis删除
        redisRemoteService.removeRedisKeyRemote(key);
        // 执行密码加密
        //String digest = MD5Util.digest(memberVO.getUserpswd());
        //memberVO.setUserpswd(digest);
        String encode = passwordEncoder.encode(memberVO.getUserpswd());
        memberVO.setUserpswd(encode);
        // 执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);
        ResultEntity<String> resultEntity = mysqlRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(resultEntity.getResult())) {
            modelMap.addAttribute("message", resultEntity.getMessage());
            return "member-reg";
        }
        // 使用重定向，避免刷新浏览器重新执行注册流程
        return "redirect:/auth/member/to/login/page";
    }

    @RequestMapping("/auth/member/do/login")
    private String login(@RequestParam("loginacct") String loginacct,
                         @RequestParam("userpswd") String userpswd,
                         ModelMap modelMap,
                         HttpSession httpSession) {
        ResultEntity<MemberPO> result = mysqlRemoteService.getMemberPOLoginAcctRemote(loginacct);
        if (ResultEntity.FAILED.equals(result.getResult())) {
            modelMap.addAttribute("message", result.getMessage());
            return "member-login";
        }
        MemberPO memberPO = result.getData();
        if (memberPO == null) {
            modelMap.addAttribute("message", "用户名不对！");
            return "member-login";
        }
        String userpswdFromDB = memberPO.getUserpswd();
        boolean matches = passwordEncoder.matches(userpswd, userpswdFromDB);
        if (!matches) {
            modelMap.addAttribute("message", "用户密码不对！");
            return  "member-login";
        }
        MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
        httpSession.setAttribute("loginMember", memberLoginVO);
        return "redirect:/auth/member/to/center/page";
    }

    @RequestMapping("/auth/member/logout")
    public String logout(HttpSession httpSession) {
        httpSession.invalidate();
        return "redirect:/";
    }


}
